package com.cinema;

import com.cinema.entity.Movie;
import com.cinema.entity.Schedule;
import com.cinema.entity.ScreeningRoom;
import com.cinema.entity.User;
import com.cinema.entity.Role;
import com.cinema.exception.SeatException;
import com.cinema.service.CinemaService;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 电影院管理系统主类
 * 包含完整的测试用例来演示系统功能
 */
public class CinemaSystem {
    
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    
    public static void main(String[] args) {
        System.out.println("=== 电影院管理系统整体测试开始 ===\n");

        // 第一轮迭代：单用户功能CASE
        runV1SingleUserCases();

        // 第二轮迭代：多用户与权限体系CASE
        runV2MultiUserCases();

        System.out.println("\n=== 电影院管理系统整体测试完成 ===");
    }

    // 第一轮迭代：单用户功能CASE
    private static void runV1SingleUserCases() {
        System.out.println("\n--- 第一轮迭代：单用户功能CASE ---\n");
        CinemaService service = new CinemaService();
        try {
            testAddMoviesAndRoomsLegacy(service);
            testCreateSchedulesLegacy(service);
            testQueryFunctionsLegacy(service);
            testTicketSellingLegacy(service);
            testExceptionCasesLegacy(service);
        } catch (Exception e) {
            System.err.println("单用户CASE测试过程中发生异常：" + e.getMessage());
            e.printStackTrace();
        }
        System.out.println("\n--- 第一轮迭代测试完成 ---\n");
    }

    // 第二轮迭代：多用户与权限体系CASE
    private static void runV2MultiUserCases() {
        System.out.println("\n--- 第二轮迭代：多用户与权限体系CASE ---\n");
        CinemaService service = new CinemaService();
        // 创建用户
        User admin = new User("u1", "老板", Role.ADMIN, null);
        User manager = new User("u2", "店长", Role.MANAGER, "u1");
        User cashier = new User("u3", "售票员", Role.CASHIER, "u2");
        // 管理员添加店长
        service.addUser(admin, manager);
        // 店长添加售票员
        service.addUser(manager, cashier);
        // 权限CASE1：系统管理员添加电影和放映厅
        try {
            service.addMovie(admin, new Movie("m10", "多用户-流浪地球", 120));
            service.addRoom(admin, new ScreeningRoom("r10", "多用户-IMAX厅", 10, 15));
            System.out.println("管理员添加电影和放映厅：成功");
        } catch (Exception e) {
            System.out.println("管理员添加电影和放映厅：失败 - " + e.getMessage());
        }
        // 权限CASE2：店长尝试添加电影（应失败）
        try {
            service.addMovie(manager, new Movie("m20", "多用户-战狼2", 110));
            System.out.println("店长添加电影：成功（应失败）");
        } catch (Exception e) {
            System.out.println("店长添加电影：失败（预期） - " + e.getMessage());
        }
        // 权限CASE3：店长添加排片
        try {
            Movie movie = service.getAllMovies().get(0);
            ScreeningRoom room = service.getAllRooms().get(0);
            service.addSchedule(manager, new Schedule("s10", movie, room, java.time.LocalDateTime.now().plusHours(1), java.time.LocalDateTime.now().plusHours(3)));
            System.out.println("店长添加排片：成功");
        } catch (Exception e) {
            System.out.println("店长添加排片：失败 - " + e.getMessage());
        }
        // 权限CASE4：售票员尝试添加排片（应失败）
        try {
            Movie movie = service.getAllMovies().get(0);
            ScreeningRoom room = service.getAllRooms().get(0);
            service.addSchedule(cashier, new Schedule("s20", movie, room, java.time.LocalDateTime.now().plusHours(4), java.time.LocalDateTime.now().plusHours(6)));
            System.out.println("售票员添加排片：成功（应失败）");
        } catch (Exception e) {
            System.out.println("售票员添加排片：失败（预期） - " + e.getMessage());
        }
        // 权限CASE5：售票员售票
        try {
            boolean result = service.sellTicket(cashier, "s10", 2, 3, "13800138000");
            System.out.println("售票员售票：" + (result ? "成功" : "失败"));
        } catch (Exception e) {
            System.out.println("售票员售票：失败 - " + e.getMessage());
        }
        // 权限CASE6：店长尝试售票（应失败）
        try {
            service.sellTicket(manager, "s10", 2, 4, "13900139000");
            System.out.println("店长售票：成功（应失败）");
        } catch (Exception e) {
            System.out.println("店长售票：失败（预期） - " + e.getMessage());
        }
        // 权限CASE7：管理员删除店长
        try {
            service.deleteUser(admin, manager.getId());
            System.out.println("管理员删除店长：成功");
        } catch (Exception e) {
            System.out.println("管理员删除店长：失败 - " + e.getMessage());
        }
        // 权限CASE8：店长尝试删除管理员（应失败）
        try {
            service.deleteUser(manager, admin.getId());
            System.out.println("店长删除管理员：成功（应失败）");
        } catch (Exception e) {
            System.out.println("店长删除管理员：失败（预期） - " + e.getMessage());
        }
        System.out.println("\n--- 第二轮迭代测试完成 ---\n");
    }

    // 下面是兼容单用户CASE的旧方法，适配新接口
    private static void testAddMoviesAndRoomsLegacy(CinemaService service) {
        System.out.println("【测试用例1】添加电影和放映厅");
        System.out.println("----------------------------------------");
        Movie movie1 = new Movie("m1", "流浪地球", 120);
        Movie movie2 = new Movie("m2", "战狼2", 110);
        Movie movie3 = new Movie("m3", "红海行动", 130);
        // 兼容：用管理员身份添加
        User admin = new User("legacy_admin", "兼容管理员", Role.ADMIN, null);
        service.addUser(admin, admin);
        service.addMovie(admin, movie1);
        service.addMovie(admin, movie2);
        service.addMovie(admin, movie3);
        ScreeningRoom room1 = new ScreeningRoom("r1", "IMAX厅", 10, 15);
        ScreeningRoom room2 = new ScreeningRoom("r2", "普通厅", 8, 12);
        ScreeningRoom room3 = new ScreeningRoom("r3", "VIP厅", 6, 8);
        service.addRoom(admin, room1);
        service.addRoom(admin, room2);
        service.addRoom(admin, room3);
        System.out.println("已添加电影：");
        service.getAllMovies().forEach(movie -> System.out.println("  " + movie.toString()));
        System.out.println("\n已添加放映厅：");
        service.getAllRooms().forEach(room -> System.out.println("  " + room.toString()));
        System.out.println();
    }
    private static void testCreateSchedulesLegacy(CinemaService service) {
        System.out.println("【测试用例2】创建排片");
        System.out.println("----------------------------------------");
        Movie movie1 = service.getMovie("m1");
        Movie movie2 = service.getMovie("m2");
        ScreeningRoom room1 = service.getRoom("r1");
        ScreeningRoom room2 = service.getRoom("r2");
        LocalDateTime now = LocalDateTime.now();
        Schedule schedule1 = new Schedule("s1", movie1, room1, now.plusHours(2), now.plusHours(4));
        Schedule schedule2 = new Schedule("s2", movie2, room2, now.plusHours(3), now.plusHours(5));
        Schedule schedule3 = new Schedule("s3", movie1, room2, now.plusHours(6), now.plusHours(8));
        // 兼容：用店长身份添加排片
        User manager = new User("legacy_manager", "兼容店长", Role.MANAGER, "legacy_admin");
        service.addUser(manager, manager);
        service.addSchedule(manager, schedule1);
        service.addSchedule(manager, schedule2);
        service.addSchedule(manager, schedule3);
        System.out.println("已创建排片：");
        service.getAllSchedules().forEach(schedule -> System.out.println("  " + schedule.toString()));
        System.out.println();
    }
    private static void testQueryFunctionsLegacy(CinemaService service) {
        System.out.println("【测试用例3】查询功能测试");
        System.out.println("----------------------------------------");
        System.out.println("1. 按电影查询 - '流浪地球'的排片：");
        List<Schedule> movieSchedules = service.queryByMovie("流浪地球");
        movieSchedules.forEach(schedule -> System.out.println("  " + schedule.getRoom().getName() + " - " + schedule.getStartTime().format(formatter)));
        System.out.println("\n2. 按放映厅查询 - 'IMAX厅'的排片：");
        List<Schedule> roomSchedules = service.queryByRoom("r1");
        roomSchedules.forEach(schedule -> System.out.println("  " + schedule.getMovie().getName() + " - " + schedule.getStartTime().format(formatter)));
        System.out.println("\n3. 按时间查询 - 未来4小时内的排片：");
        LocalDateTime start = LocalDateTime.now();
        LocalDateTime end = start.plusHours(4);
        List<Schedule> timeSchedules = service.queryByTime(start, end);
        timeSchedules.forEach(schedule -> System.out.println("  " + schedule.getMovie().getName() + " - " + schedule.getRoom().getName() + " - " + schedule.getStartTime().format(formatter)));
        System.out.println("\n4. 当前上映的电影：");
        List<Movie> currentMovies = service.getCurrentMovies();
        currentMovies.forEach(movie -> System.out.println("  " + movie.getName()));
        System.out.println();
    }
    private static void testTicketSellingLegacy(CinemaService service) {
        System.out.println("【测试用例4】售票功能测试");
        System.out.println("----------------------------------------");
        String scheduleId = "s1";
        System.out.println("排片 " + scheduleId + " 的座位统计：");
        System.out.println("  " + service.getSeatStatistics(scheduleId));
        System.out.println("\n开始售票测试：");
        try {
            // 兼容：用售票员身份售票
            User cashier = new User("legacy_cashier", "兼容售票员", Role.CASHIER, "legacy_manager");
            service.addUser(cashier, cashier);
            boolean success1 = service.sellTicket(cashier, scheduleId, 3, 5, "13800138000");
            System.out.println("  售票1（行3列5）：" + (success1 ? "成功" : "失败"));
            boolean success2 = service.sellTicket(cashier, scheduleId, 4, 6, "13900139000");
            System.out.println("  售票2（行4列6）：" + (success2 ? "成功" : "失败"));
            System.out.println("\n售票后的座位统计：");
            System.out.println("  " + service.getSeatStatistics(scheduleId));
        } catch (SeatException e) {
            System.err.println("  售票异常：" + e.getMessage());
        }
        System.out.println();
    }
    private static void testExceptionCasesLegacy(CinemaService service) {
        System.out.println("【测试用例5】异常情况测试");
        System.out.println("----------------------------------------");
        String scheduleId = "s1";
        try {
            User cashier = new User("legacy_cashier", "兼容售票员", Role.CASHIER, "legacy_manager");
            service.addUser(cashier, cashier);
            System.out.println("1. 测试重复售票（行3列5）：");
            service.sellTicket(cashier, scheduleId, 3, 5, "13700137000");
        } catch (SeatException e) {
            System.out.println("   异常：" + e.getMessage());
        }
        try {
            User cashier = new User("legacy_cashier", "兼容售票员", Role.CASHIER, "legacy_manager");
            service.addUser(cashier, cashier);
            System.out.println("\n2. 测试座位不存在（行20列30）：");
            service.sellTicket(cashier, scheduleId, 20, 30, "13600136000");
        } catch (SeatException e) {
            System.out.println("   异常：" + e.getMessage());
        }
        try {
            User cashier = new User("legacy_cashier", "兼容售票员", Role.CASHIER, "legacy_manager");
            service.addUser(cashier, cashier);
            System.out.println("\n3. 测试排片不存在：");
            service.sellTicket(cashier, "不存在的排片ID", 1, 1, "13500135000");
        } catch (SeatException e) {
            System.out.println("   异常：" + e.getMessage());
        }
        try {
            User manager = new User("legacy_manager", "兼容店长", Role.MANAGER, "legacy_admin");
            service.addUser(manager, manager);
            System.out.println("\n4. 测试时间冲突排片：");
            Movie movie1 = service.getMovie("m1");
            ScreeningRoom room1 = service.getRoom("r1");
            LocalDateTime now = LocalDateTime.now();
            Schedule conflictSchedule = new Schedule("s4", movie1, room1, now.plusHours(2).plusMinutes(30), now.plusHours(4).plusMinutes(30));
            service.addSchedule(manager, conflictSchedule);
        } catch (IllegalArgumentException e) {
            System.out.println("   异常：" + e.getMessage());
        }
        System.out.println();
    }
} 